home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / src / symtab.cc < prev    next >
C/C++ Source or Header  |  1996-10-15  |  21KB  |  1,198 lines

  1. /*
  2.  
  3. Copyright (C) 1996 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. #if defined (__GNUG__)
  24. #pragma implementation
  25. #endif
  26.  
  27. #ifdef HAVE_CONFIG_H
  28. #include <config.h>
  29. #endif
  30.  
  31. #include <cctype>
  32.  
  33. #include "oct-glob.h"
  34. #include "str-vec.h"
  35.  
  36. #include "error.h"
  37. #include "pt-const.h"
  38. #include "pt-fcn.h"
  39. #include "pt-fvc.h"
  40. #include "symtab.h"
  41. #include "utils.h"
  42. #include "variables.h"
  43.  
  44. // Variables and functions.
  45.  
  46. symbol_def::symbol_def (void)
  47. {
  48.   init_state ();
  49. }
  50.  
  51. symbol_def::symbol_def (tree_constant *t)
  52. {
  53.   init_state ();
  54.   definition = t;
  55.   type = USER_VARIABLE;
  56. }
  57.  
  58. symbol_def::symbol_def (tree_builtin *t, unsigned fcn_type)
  59. {
  60.   init_state ();
  61.   definition = t;
  62.   type = BUILTIN_FUNCTION | fcn_type;
  63. }
  64.  
  65. symbol_def::symbol_def (tree_function *t, unsigned fcn_type)
  66. {
  67.   init_state ();
  68.   definition = t;
  69.   type = USER_FUNCTION | fcn_type;
  70. }
  71.  
  72. void
  73. symbol_def::init_state (void)
  74. {
  75.   type = UNKNOWN;
  76.   eternal = 0;
  77.   read_only = 0;
  78.  
  79.   definition = 0;
  80.   next_elem = 0;
  81.   count = 0;
  82. }
  83.  
  84. symbol_def::~symbol_def (void)
  85. {
  86.   delete definition;
  87. }
  88.  
  89. int
  90. symbol_def::is_variable (void) const
  91. {
  92.   return (type & USER_VARIABLE || type & BUILTIN_VARIABLE);
  93. }
  94.  
  95. int
  96. symbol_def::is_function (void) const
  97. {
  98.   return (type & USER_FUNCTION || type & BUILTIN_FUNCTION);
  99. }
  100.  
  101. int
  102. symbol_def::is_user_variable (void) const
  103. {
  104.   return (type & USER_VARIABLE);
  105. }
  106.  
  107. int
  108. symbol_def::is_text_function (void) const
  109. {
  110.   return (type & TEXT_FUNCTION);
  111. }
  112.  
  113. int
  114. symbol_def::is_mapper_function (void) const
  115. {
  116.   return (type & MAPPER_FUNCTION);
  117. }
  118.  
  119. int
  120. symbol_def::is_user_function (void) const
  121. {
  122.   return (type & USER_FUNCTION);
  123. }
  124.  
  125. int
  126. symbol_def::is_builtin_variable (void) const
  127. {
  128.   return (type & BUILTIN_VARIABLE);
  129. }
  130.  
  131. int
  132. symbol_def::is_builtin_function (void) const
  133. {
  134.   return (type & BUILTIN_FUNCTION);
  135. }
  136.  
  137. // XXX FIXME XXX
  138. int
  139. symbol_def::is_map_element (const string& /* elts */) const
  140. {
  141.   return 0;
  142. }
  143.  
  144. void
  145. symbol_def::define (tree_constant *t)
  146. {
  147.   if (t)
  148.     t->maybe_mutate ();
  149.  
  150.   definition = t;
  151.  
  152.   if (! is_builtin_variable ())
  153.     type = USER_VARIABLE;
  154. }
  155.  
  156. void
  157. symbol_def::define (tree_builtin *t, unsigned fcn_type)
  158. {
  159.   definition = t;
  160.   type = BUILTIN_FUNCTION | fcn_type;
  161. }
  162.  
  163. void
  164. symbol_def::define (tree_function *t, unsigned fcn_type)
  165. {
  166.   definition = t;
  167.   type = USER_FUNCTION | fcn_type;
  168. }
  169.  
  170. void
  171. symbol_def::protect (void)
  172. {
  173.   read_only = 1;
  174. }
  175.  
  176. void
  177. symbol_def::unprotect (void)
  178. {
  179.   read_only = 0;
  180.  
  181. }
  182.  
  183. void
  184. symbol_def::make_eternal (void)
  185. {
  186.   eternal = 1;
  187. }
  188.  
  189. tree_fvc *
  190. symbol_def::def (void) const
  191. {
  192.   return definition;
  193. }
  194.  
  195. string
  196. symbol_def::help (void) const
  197. {
  198.   return help_string;
  199. }
  200.  
  201. void
  202. symbol_def::document (const string& h)
  203. {
  204.   help_string = h;
  205. }
  206.  
  207. int
  208. maybe_delete (symbol_def *def)
  209. {
  210.   int count = 0;
  211.   if (def && def->count > 0)
  212.     {
  213.       def->count--;
  214.       count = def->count;
  215.       if (def->count == 0)
  216.     delete def;
  217.     }
  218.   return count;
  219. }
  220.  
  221. // Individual records in a symbol table.
  222.  
  223. symbol_record::symbol_record (void)
  224. {
  225.   init_state ();
  226. }
  227.  
  228. symbol_record::symbol_record (const string& n, symbol_record *nxt)
  229. {
  230.   init_state ();
  231.   nm = n;
  232.   next_elem = nxt;
  233. }
  234.  
  235. void
  236. symbol_record::init_state (void)
  237. {
  238.   formal_param = 0;
  239.   linked_to_global = 0;
  240.   sv_fcn = 0;
  241.   definition = 0;
  242.   next_elem = 0;
  243. }
  244.  
  245. string
  246. symbol_record::name (void) const
  247. {
  248.   return nm;
  249. }
  250.  
  251. string
  252. symbol_record::help (void) const
  253. {
  254.   string retval;
  255.   if (definition)
  256.     retval = definition->help ();
  257.   return retval;
  258. }
  259.  
  260. tree_fvc *
  261. symbol_record::def (void) const
  262. {
  263.   return definition ? definition->def () : 0;
  264. }
  265.  
  266. void
  267. symbol_record::rename (const string& new_name)
  268. {
  269.   nm = new_name;
  270. }
  271.  
  272. int
  273. symbol_record::is_function (void) const
  274. {
  275.   return definition ? definition->is_function () : 0;
  276. }
  277.  
  278. int
  279. symbol_record::is_text_function (void) const
  280. {
  281.   return definition ? definition->is_text_function () : 0;
  282. }
  283.  
  284. int
  285. symbol_record::is_mapper_function (void) const
  286. {
  287.   return definition ? definition->is_mapper_function () : 0;
  288. }
  289.  
  290. int
  291. symbol_record::is_user_function (void) const
  292. {
  293.   return definition ? definition->is_user_function () : 0;
  294. }
  295.  
  296. int
  297. symbol_record::is_builtin_function (void) const
  298. {
  299.   return definition ? definition->is_builtin_function () : 0;
  300. }
  301.  
  302. int
  303. symbol_record::is_variable (void) const
  304. {
  305.   return definition ? definition->is_variable () : 0;
  306. }
  307.  
  308. int
  309. symbol_record::is_user_variable (void) const
  310. {
  311.   return definition ? definition->is_user_variable () : 0;
  312. }
  313.  
  314. int
  315. symbol_record::is_builtin_variable (void) const
  316. {
  317.   return definition ? definition->is_builtin_variable () : 0;
  318. }
  319.  
  320. int
  321. symbol_record::is_map_element (const string& elts) const
  322. {
  323.   return definition ? definition->is_map_element (elts) : 0;
  324. }
  325.  
  326. unsigned
  327. symbol_record::type (void) const
  328. {
  329.   return definition ? definition->type : 0;
  330. }
  331.  
  332. int
  333. symbol_record::is_defined (void) const
  334. {
  335.   return definition ? (definition->def () != 0) : 0;
  336. }
  337.  
  338. int
  339. symbol_record::is_read_only (void) const
  340. {
  341.   return definition ? definition->read_only : 0;
  342. }
  343.  
  344. int
  345. symbol_record::is_eternal (void) const
  346. {
  347.   return definition ? definition->eternal : 0;
  348. }
  349.  
  350. void
  351. symbol_record::protect (void)
  352. {
  353.   if (definition)
  354.     {
  355.       definition->protect ();
  356.  
  357.       if (! is_defined ())
  358.     warning ("protecting undefined variable `%s'", nm.c_str ());
  359.     }
  360. }
  361.  
  362. void
  363. symbol_record::unprotect (void)
  364. {
  365.   if (definition)
  366.     definition->unprotect ();
  367. }
  368.  
  369. void
  370. symbol_record::make_eternal (void)
  371. {
  372.   if (definition)
  373.     {
  374.       definition->make_eternal ();
  375.  
  376.       if (! is_defined ())
  377.     warning ("giving eternal life to undefined variable `%s'",
  378.          nm.c_str ());
  379.     }
  380. }
  381.  
  382. void
  383. symbol_record::set_sv_function (sv_Function f)
  384. {
  385.   sv_fcn = f;
  386. }
  387.  
  388. int
  389. symbol_record::define (tree_constant *t)
  390. {
  391.   if (is_variable () && read_only_error ())
  392.     return 0;
  393.  
  394.   tree_fvc *saved_def = 0;
  395.   if (! definition)
  396.     {
  397.       definition = new symbol_def ();
  398.       definition->count = 1;
  399.     }
  400.   else if (is_function ())
  401.     {
  402.       symbol_def *new_def = new symbol_def ();
  403.       push_def (new_def);
  404.       definition->count = 1;
  405.     }
  406.   else if (is_variable ())
  407.     {
  408.       saved_def = definition->def ();
  409.     }
  410.  
  411.   definition->define (t);
  412.  
  413.   if (sv_fcn && sv_fcn () < 0)
  414.     {
  415.       // Would be nice to be able to avoid this cast.  XXX FIXME XXX
  416.  
  417.       definition->define ((tree_constant *) saved_def);
  418.       return 0;
  419.     }
  420.  
  421.   delete saved_def;
  422.  
  423.   return 1;
  424. }
  425.  
  426. int
  427. symbol_record::define (const octave_value& v)
  428. {
  429.   tree_constant *t = new tree_constant (v);
  430.   return define (t);
  431. }
  432.  
  433. int
  434. symbol_record::define (tree_builtin *t, int text_fcn)
  435. {
  436.   if (read_only_error ())
  437.     return 0;
  438.  
  439.   if (is_variable ())
  440.     {
  441.       symbol_def *old_def = pop_def ();
  442.       maybe_delete (old_def);
  443.     }
  444.  
  445.   if (is_function ())
  446.     {
  447.       symbol_def *old_def = pop_def ();
  448.       maybe_delete (old_def);
  449.     }
  450.  
  451.   unsigned fcn_type = text_fcn ? symbol_def::TEXT_FUNCTION
  452.     : ((t && t->is_mapper_function ()) ? symbol_def::MAPPER_FUNCTION
  453.        : symbol_def::UNKNOWN);
  454.  
  455.   symbol_def *new_def = new symbol_def (t, fcn_type);
  456.   push_def (new_def);
  457.   definition->count = 1;
  458.  
  459.   return 1;
  460. }
  461.  
  462. int
  463. symbol_record::define (tree_function *t, int text_fcn)
  464. {
  465.   if (read_only_error ())
  466.     return 0;
  467.  
  468.   if (is_variable ())
  469.     {
  470.       symbol_def *old_def = pop_def ();
  471.       maybe_delete (old_def);
  472.     }
  473.  
  474.   if (is_function ())
  475.     {
  476.       symbol_def *old_def = pop_def ();
  477.       maybe_delete (old_def);
  478.     }
  479.  
  480.   unsigned fcn_type = text_fcn ? symbol_def::TEXT_FUNCTION
  481.     : symbol_def::UNKNOWN;
  482.  
  483.   symbol_def *new_def = new symbol_def (t, fcn_type);
  484.   push_def (new_def);
  485.   definition->count = 1;
  486.  
  487.   return 1;
  488. }
  489.  
  490. int
  491. symbol_record::define_as_fcn (const octave_value& v)
  492. {
  493.   if (is_variable () && read_only_error ())
  494.     return 0;
  495.  
  496.   if (is_variable ())
  497.     {
  498.       symbol_def *old_def = pop_def ();
  499.       maybe_delete (old_def);
  500.     }
  501.  
  502.   if (is_function ())
  503.     {
  504.       symbol_def *old_def = pop_def ();
  505.       maybe_delete (old_def);
  506.     }
  507.  
  508.   tree_constant *t = new tree_constant (v);
  509.   symbol_def *new_def = new symbol_def (t);
  510.   push_def (new_def);
  511.   definition->count = 1;
  512.   definition->type = symbol_def::BUILTIN_FUNCTION;
  513.  
  514.   return 1;
  515. }
  516.  
  517. int
  518. symbol_record::define_builtin_var (const octave_value& v)
  519. {
  520.   tree_constant *t = new tree_constant (v);
  521.   define (t);
  522.   if (is_variable ())
  523.     definition->type = symbol_def::BUILTIN_VARIABLE;
  524.   return 1;
  525. }
  526.  
  527. void
  528. symbol_record::document (const string& h)
  529. {
  530.   if (definition)
  531.     {
  532.       definition->document (h);
  533.  
  534.       if (! is_defined ())
  535.     warning ("documenting undefined variable `%s'", nm.c_str ());
  536.     }
  537. }
  538.  
  539. int
  540. symbol_record::clear (void)
  541. {
  542.   int count = 0;
  543.   if (linked_to_global)
  544.     {
  545.       count = maybe_delete (definition);
  546.       definition = 0;
  547.       linked_to_global = 0;
  548.     }
  549.   else
  550.     {
  551.       symbol_def *old_def = pop_def ();
  552.       count = maybe_delete (old_def);
  553.     }
  554.   return count;
  555. }
  556.  
  557. void
  558. symbol_record::alias (symbol_record *s, int force)
  559. {
  560.   sv_fcn = s->sv_fcn;
  561.  
  562.   if (force && ! s->definition)
  563.     {
  564.       s->definition = new symbol_def ();
  565.       definition = s->definition;
  566.       definition->count = 2; // Yes, this is correct.
  567.     }
  568.   else if (s->definition)
  569.     {
  570.       definition = s->definition;
  571.       definition->count++;
  572.     }
  573. }
  574.  
  575. void
  576. symbol_record::mark_as_formal_parameter (void)
  577. {
  578.   formal_param = 1;
  579. }
  580.  
  581. int
  582. symbol_record::is_formal_parameter (void) const
  583. {
  584.   return formal_param;
  585. }
  586.  
  587. void
  588. symbol_record::mark_as_linked_to_global (void)
  589. {
  590.   linked_to_global = 1;
  591. }
  592.  
  593. int
  594. symbol_record::is_linked_to_global (void) const
  595. {
  596.   return linked_to_global;
  597. }
  598.  
  599. octave_value
  600. symbol_record::variable_value (void) const
  601. {
  602.   octave_value retval;
  603.  
  604.   if (is_variable ())
  605.     {
  606.       tree_constant *tmp = (tree_constant *) def ();
  607.       retval = tmp->value ();
  608.     }
  609.  
  610.   return retval;
  611. }
  612.  
  613. octave_value&
  614. symbol_record::variable_reference (void)
  615. {
  616.   if (is_function ())
  617.     clear ();
  618.  
  619.   if (! is_defined ())
  620.     {
  621.       if (! (is_formal_parameter () || is_linked_to_global ()))
  622.     link_to_builtin_variable (this);
  623.  
  624.       if (! is_defined ())
  625.     {
  626.       tree_constant *tmp = new tree_constant ();
  627.       define (tmp);
  628.     }
  629.     }
  630.  
  631.   tree_constant *tmp = (tree_constant *) def ();
  632.  
  633.   return tmp->reference ();
  634. }
  635.  
  636. symbol_record *
  637. symbol_record::next (void) const
  638. {
  639.   return next_elem;
  640. }
  641.  
  642. void
  643. symbol_record::chain (symbol_record *s)
  644. {
  645.   next_elem = s;
  646. }
  647.  
  648. void
  649. symbol_record::push_context (void)
  650. {
  651.   context.push (definition);
  652.   definition = 0;
  653.  
  654.   global_link_context.push ((unsigned) linked_to_global);
  655.   linked_to_global = 0;
  656. }
  657.  
  658. void
  659. symbol_record::pop_context (void)
  660. {
  661.   // It is possible for context to be empty if new symbols have been
  662.   // inserted in the symbol table during recursive calls.  This can
  663.   // happen as a result of calls to eval() and feval().
  664.  
  665.   if (! context.empty ())
  666.     {
  667.       if (is_variable ())
  668.     {
  669.       symbol_def *old_def = pop_def ();
  670.       maybe_delete (old_def);
  671.     }
  672.  
  673.       if (is_function ())
  674.     {
  675.       symbol_def *old_def = pop_def ();
  676.       maybe_delete (old_def);
  677.     }
  678.  
  679.       definition = context.pop ();
  680.       linked_to_global = global_link_context.pop ();
  681.     }
  682. }
  683.  
  684. int
  685. symbol_record::read_only_error (void)
  686. {
  687.   if (is_read_only ())
  688.     {
  689.       if (is_variable ())
  690.     {
  691.       ::error ("can't redefine read-only constant `%s'", nm.c_str ());
  692.     }
  693.       else if (is_function ())
  694.     {
  695.       ::error ("can't redefine read-only function `%s'", nm.c_str ());
  696.     }
  697.       else
  698.     {
  699.       ::error ("can't redefine read-only symbol `%s'", nm.c_str ());
  700.     }
  701.  
  702.       return 1;
  703.     }
  704.   else
  705.     return 0;
  706. }
  707.  
  708. void
  709. symbol_record::push_def (symbol_def *sd)
  710. {
  711.   if (! sd)
  712.     return;
  713.  
  714.   sd->next_elem = definition;
  715.   definition = sd;
  716. }
  717.  
  718. symbol_def *
  719. symbol_record::pop_def (void)
  720. {
  721.   symbol_def *top = definition;
  722.   if (definition)
  723.     definition = definition->next_elem;
  724.   return top;
  725. }
  726.  
  727. // A structure for handling verbose information about a symbol_record.
  728.  
  729. symbol_record_info::symbol_record_info (void)
  730.   : initialized (0), nr (-1), nc (-1), type (symbol_def::UNKNOWN),
  731.     hides (SR_INFO_NONE), eternal (0), read_only (0), nm (),
  732.     const_type () { }
  733.  
  734. symbol_record_info::symbol_record_info (const symbol_record& sr)
  735.   : initialized (0), nr (-1), nc (-1), type (sr.type ()),
  736.     hides (SR_INFO_NONE), eternal (0), read_only (0), nm (),
  737.     const_type ()
  738. {
  739.   if (sr.is_variable () && sr.is_defined ())
  740.     {
  741.       // Would be nice to avoid this cast.  XXX FIXME XXX
  742.  
  743.       tree_constant *tmp = (tree_constant *) sr.def ();
  744.  
  745.       const_type = tmp->type_name ();
  746.  
  747.       nr = tmp->rows ();
  748.       nc = tmp->columns ();
  749.  
  750.       symbol_def *sr_def = sr.definition;
  751.       symbol_def *hidden_def = sr_def->next_elem;
  752.  
  753.       if (hidden_def)
  754.     {
  755.       if (hidden_def->is_user_function ())
  756.         hides = SR_INFO_USER_FUNCTION;
  757.       else if (hidden_def->is_builtin_function ())
  758.         hides = SR_INFO_BUILTIN_FUNCTION;
  759.     }
  760.     }
  761.  
  762.   eternal = sr.is_eternal ();
  763.   read_only = sr.is_read_only ();
  764.  
  765.   nm = sr.name ();
  766.  
  767.   initialized = 1;
  768. }
  769.  
  770. symbol_record_info::symbol_record_info (const symbol_record_info& s)
  771.   : initialized (s.initialized), nr (s.nr), nc (s.nc), type (s.type),
  772.     hides (s.hides), eternal (s.eternal), read_only (s.read_only),
  773.     nm (s.nm), const_type (s.const_type) { }
  774.  
  775. symbol_record_info&
  776. symbol_record_info::operator = (const symbol_record_info& s)
  777. {
  778.   if (this != &s)
  779.     {
  780.       initialized = s.initialized;
  781.       nr = s.nr;
  782.       nc = s.nc;
  783.       type = s.type;
  784.       hides = s.hides;
  785.       eternal = s.eternal;
  786.       read_only = s.read_only;
  787.       nm = s.nm;
  788.       const_type = s.const_type;
  789.     }
  790.   return *this;
  791. }
  792.  
  793. int
  794. symbol_record_info::is_defined (void) const
  795. {
  796.   return initialized;
  797. }
  798.  
  799. int
  800. symbol_record_info::is_read_only (void) const
  801. {
  802.   return read_only;
  803. }
  804.  
  805. int
  806. symbol_record_info::is_eternal (void) const
  807. {
  808.   return eternal;
  809. }
  810.  
  811. int
  812. symbol_record_info::hides_fcn (void) const
  813. {
  814.   return (hides & SR_INFO_USER_FUNCTION);
  815. }
  816.  
  817. int
  818. symbol_record_info::hides_builtin (void) const
  819. {
  820.   return (hides & SR_INFO_BUILTIN_FUNCTION);
  821. }
  822.  
  823. string
  824. symbol_record_info::type_name (void) const
  825. {
  826.   string retval;
  827.  
  828.   if (type == symbol_def::USER_FUNCTION)
  829.     retval = "user function";
  830.   else if (type & symbol_def::BUILTIN_FUNCTION)
  831.     {
  832.       if (type & symbol_def::TEXT_FUNCTION)
  833.     retval = "text function";
  834.       else if (type & symbol_def::MAPPER_FUNCTION)
  835.     retval = "mapper function";
  836.       else
  837.     retval = "builtin function";
  838.     }
  839.   else
  840.     retval = const_type;
  841.  
  842.   return retval;
  843. }
  844.  
  845. int
  846. symbol_record_info::is_function (void) const
  847. {
  848.   return (type == symbol_def::USER_FUNCTION
  849.       || type == symbol_def::BUILTIN_FUNCTION
  850.       || symbol_def::TEXT_FUNCTION
  851.       || symbol_def::MAPPER_FUNCTION);
  852. }
  853.  
  854. int
  855. symbol_record_info::rows (void) const
  856. {
  857.   return nr;
  858. }
  859.  
  860. int
  861. symbol_record_info::columns (void) const
  862. {
  863.   return nc;
  864. }
  865.  
  866. string
  867. symbol_record_info::name (void) const
  868. {
  869.   return nm;
  870. }
  871.  
  872. // A symbol table.
  873.  
  874. symbol_table::symbol_table (void)
  875. {
  876. }
  877.  
  878. symbol_record *
  879. symbol_table::lookup (const string& nm, int insert, int warn)
  880. {
  881.   int index = hash (nm) & HASH_MASK;
  882.  
  883.   symbol_record *ptr = table[index].next ();
  884.  
  885.   while (ptr)
  886.     {
  887.       if (ptr->name () == nm)
  888.     return ptr;
  889.       ptr = ptr->next ();
  890.     }
  891.  
  892.   if (insert)
  893.     {
  894.       symbol_record *new_sym;
  895.       new_sym = new symbol_record (nm, table[index].next ());
  896.       table[index].chain (new_sym);
  897.       return new_sym;
  898.     }
  899.   else if (warn)
  900.     warning ("lookup: symbol`%s' not found", nm.c_str ());
  901.  
  902.   return 0;
  903. }
  904.  
  905. void
  906. symbol_table::rename (const string& old_name, const string& new_name)
  907. {
  908.   int index = hash (old_name) & HASH_MASK;
  909.  
  910.   symbol_record *prev = &table[index];
  911.   symbol_record *ptr = prev->next ();
  912.  
  913.   while (ptr)
  914.     {
  915.       if (ptr->name () == old_name)
  916.     {
  917.       prev->chain (ptr->next ());
  918.  
  919.       index = hash (new_name) & HASH_MASK;
  920.       table[index].chain (ptr);
  921.       ptr->rename (new_name);
  922.  
  923.       return;
  924.     }
  925.  
  926.       prev = ptr;
  927.       ptr = ptr->next ();
  928.     }
  929.  
  930.   error ("unable to rename `%s' to `%s'", old_name.c_str (),
  931.      new_name.c_str ());
  932. }
  933.  
  934. void
  935. symbol_table::clear (int clear_user_functions)
  936. {
  937.   for (int i = 0; i < HASH_TABLE_SIZE; i++)
  938.     {
  939.       symbol_record *ptr = table[i].next ();
  940.  
  941.       while (ptr)
  942.     {
  943.       if (ptr->is_user_variable ()
  944.           || (clear_user_functions && ptr->is_user_function ()))
  945.         {
  946.           ptr->clear ();
  947.         }
  948.  
  949.       ptr = ptr->next ();
  950.     }
  951.     }
  952. }
  953.  
  954. int
  955. symbol_table::clear (const string& nm, int clear_user_functions)
  956. {
  957.   int index = hash (nm) & HASH_MASK;
  958.  
  959.   symbol_record *ptr = table[index].next ();
  960.  
  961.   while (ptr)
  962.     {
  963.       if (ptr->name () == nm
  964.       && (ptr->is_user_variable ()
  965.           || (clear_user_functions && ptr->is_user_function ())))
  966.     {
  967.       ptr->clear ();
  968.       return 1;
  969.     }
  970.       ptr = ptr->next ();
  971.     }
  972.  
  973.   return 0;
  974. }
  975.  
  976. int
  977. symbol_table::size (void) const
  978. {
  979.   int count = 0;
  980.   for (int i = 0; i < HASH_TABLE_SIZE; i++)
  981.     {
  982.       symbol_record *ptr = table[i].next ();
  983.       while (ptr)
  984.     {
  985.       count++;
  986.       ptr = ptr->next ();
  987.     }
  988.     }
  989.   return count;
  990. }
  991.  
  992. static inline int
  993. pstrcmp (char **a, char **b)
  994. {
  995.   return strcmp (*a, *b);
  996. }
  997.  
  998. static inline int
  999. symbol_record_info_cmp (symbol_record_info *a, symbol_record_info *b)
  1000. {
  1001.   return (a->name () == b->name ());
  1002. }
  1003.  
  1004. static int
  1005. matches_patterns (const string& name, const string_vector& pats, int npats)
  1006. {
  1007.   for (int i = 0; i < npats; i++)
  1008.     {
  1009.       glob_match pattern (pats[i]);
  1010.       if (pattern.match (name))
  1011.     return 1;
  1012.     }
  1013.  
  1014.   return 0;
  1015. }
  1016.  
  1017. // This function should probably share code with symbol_table::list.
  1018. // XXX FIXME XXX
  1019.  
  1020. symbol_record_info *
  1021. symbol_table::long_list (int& count, const string_vector& pats,
  1022.              int npats, int sort, unsigned type,
  1023.              unsigned scope) const 
  1024. {
  1025.   count = 0;
  1026.   int n = size ();
  1027.   if (n == 0)
  1028.     return 0;
  1029.  
  1030.   symbol_record_info *symbols = new symbol_record_info [n+1];
  1031.   for (int i = 0; i < HASH_TABLE_SIZE; i++)
  1032.     {
  1033.       symbol_record *ptr = table[i].next ();
  1034.       while (ptr)
  1035.     {
  1036.       assert (count < n);
  1037.  
  1038.       unsigned my_scope = ptr->is_linked_to_global () + 1; // Tricky...
  1039.  
  1040.       unsigned my_type = ptr->type ();
  1041.  
  1042.       string my_name = ptr->name ();
  1043.  
  1044.       if ((type & my_type) && (scope & my_scope)
  1045.           && (npats == 0 || matches_patterns (my_name, pats, npats)))
  1046.         symbols[count++] = symbol_record_info (*ptr);
  1047.  
  1048.       ptr = ptr->next ();
  1049.     }
  1050.     }
  1051.   symbols[count] = symbol_record_info ();
  1052.  
  1053.   if (sort && symbols)
  1054.     qsort ((void *) symbols, count, sizeof (symbol_record_info),
  1055.        (int (*)(const void*, const void*)) symbol_record_info_cmp);
  1056.  
  1057.   return symbols;
  1058. }
  1059.  
  1060. string_vector
  1061. symbol_table::list (int& count, const string_vector& pats, int npats,
  1062.             int sort, unsigned type, unsigned scope) const
  1063. {
  1064.   count = 0;
  1065.   int n = size ();
  1066.   if (n == 0)
  1067.     return 0;
  1068.  
  1069.   string_vector symbols (n);
  1070.  
  1071.   for (int i = 0; i < HASH_TABLE_SIZE; i++)
  1072.     {
  1073.       symbol_record *ptr = table[i].next ();
  1074.       while (ptr)
  1075.     {
  1076.       assert (count < n);
  1077.  
  1078.       unsigned my_scope = ptr->is_linked_to_global () + 1; // Tricky...
  1079.  
  1080.       unsigned my_type = ptr->type ();
  1081.  
  1082.       string my_name = ptr->name ();
  1083.  
  1084.       if ((type & my_type) && (scope & my_scope)
  1085.           && (npats == 0 || matches_patterns (my_name, pats, npats)))
  1086.         symbols[count++] = ptr->name ();
  1087.  
  1088.       ptr = ptr->next ();
  1089.     }
  1090.     }
  1091.  
  1092.   symbols.resize (count);
  1093.  
  1094.   if (sort && ! symbols.empty ())
  1095.     symbols.qsort ();
  1096.  
  1097.   return symbols;
  1098. }
  1099.  
  1100. symbol_record **
  1101. symbol_table::glob (int& count, const string& pat, unsigned type,
  1102.             unsigned scope) const
  1103. {
  1104.   count = 0;
  1105.   int n = size ();
  1106.   if (n == 0)
  1107.     return 0;
  1108.  
  1109.   symbol_record **symbols = new symbol_record * [n+1];
  1110.   for (int i = 0; i < HASH_TABLE_SIZE; i++)
  1111.     {
  1112.       symbol_record *ptr = table[i].next ();
  1113.       while (ptr)
  1114.     {
  1115.       assert (count < n);
  1116.  
  1117.       unsigned my_scope = ptr->is_linked_to_global () + 1; // Tricky...
  1118.  
  1119.       unsigned my_type = ptr->type ();
  1120.  
  1121.       glob_match pattern (pat);
  1122.  
  1123.       if ((type & my_type) && (scope & my_scope)
  1124.           && pattern.match (ptr->name ()))
  1125.         {
  1126.           symbols[count++] = ptr;
  1127.         }
  1128.  
  1129.       ptr = ptr->next ();
  1130.     }
  1131.     }
  1132.   symbols[count] = 0;
  1133.  
  1134.   return symbols;
  1135. }
  1136.  
  1137. void
  1138. symbol_table::push_context (void)
  1139. {
  1140.   for (int i = 0; i < HASH_TABLE_SIZE; i++)
  1141.     {
  1142.       symbol_record *ptr = table[i].next ();
  1143.  
  1144.       while (ptr)
  1145.     {
  1146.       ptr->push_context ();
  1147.       ptr = ptr->next ();
  1148.     }
  1149.     }
  1150. }
  1151.  
  1152. void
  1153. symbol_table::pop_context (void)
  1154. {
  1155.   for (int i = 0; i < HASH_TABLE_SIZE; i++)
  1156.     {
  1157.       symbol_record *ptr = table[i].next ();
  1158.  
  1159.       while (ptr)
  1160.     {
  1161.       ptr->pop_context ();
  1162.       ptr = ptr->next ();
  1163.     }
  1164.     }
  1165. }
  1166.  
  1167. // Chris Torek's fave hash function.
  1168.  
  1169. unsigned int
  1170. symbol_table::hash (const string& str)
  1171. {
  1172.   unsigned h = 0;
  1173.   for (unsigned i = 0; i < str.length (); i++)
  1174.     h = h * 33 + str[i];
  1175.   return h;
  1176. }
  1177.  
  1178. // Return nonzero if S is a valid identifier.
  1179.  
  1180. int
  1181. valid_identifier (const char *s)
  1182. {
  1183.   if (! s || ! (isalnum (*s) || *s == '_'))
  1184.      return 0;
  1185.  
  1186.   while (*++s != '\0')
  1187.     if (! (isalnum (*s) || *s == '_'))
  1188.       return 0;
  1189.  
  1190.   return 1;
  1191. }
  1192.  
  1193. /*
  1194. ;;; Local Variables: ***
  1195. ;;; mode: C++ ***
  1196. ;;; End: ***
  1197. */
  1198.